#pragma once
#include <string>
#include <list>
#include <mutex>
#include <fstream>
#include <thread>
#include <condition_variable>

#include "../ini/SimpleIni.h"
#include "zqlog_enum.h"

#define ZQLOG_PLUGIN_KAFKA
#ifdef ZQLOG_PLUGIN_KAFKA
#include <librdkafka/rdkafka.h>
#endif
using std::string;

namespace libzq
{
	struct ZQLogPluginImpl
	{
		virtual ~ZQLogPluginImpl() { destory(); }
		virtual void init(const CSimpleIniA& ini) = 0;
		virtual void emit(ZQLogLevel log_level, const string& log_msg) = 0;
		virtual void destory() {};
	};

	struct ZQConsolePlugin : ZQLogPluginImpl
	{
		virtual void init(const CSimpleIniA& ini);
		virtual void emit(ZQLogLevel log_level, const string& log_msg);
		virtual void destory();

	private:
		ZQLogColor level_color(ZQLogLevel log);
		void set_color(ZQLogColor color);
	};

	struct ZQFilePlugin : ZQLogPluginImpl
	{
		virtual void init(const CSimpleIniA& ini);
		virtual void emit(ZQLogLevel log_level, const string& log_msg);
		virtual void destory();

	private:
		void run();
		string current_date();
	private:
		bool _stop;
		std::string _log_msg;
		std::mutex _mutex;
		std::thread _thread;
		std::ofstream _log_stream;
		std::condition_variable _cond_var;
	};

#ifdef ZQLOG_PLUGIN_KAFKA

	struct ZQKafkaPlugin : ZQLogPluginImpl
	{
		virtual void init(const CSimpleIniA& ini);
		virtual void emit(ZQLogLevel log_level, const string& log_msg);
		virtual void destory();

	private:
		void init_kafka(int partition, const char* brokers, const char* topic);
	private:
		bool _init_success;
		int _partition;

		//rd  
		rd_kafka_t* _handler;
		rd_kafka_conf_t *_conf;

		//topic  
		rd_kafka_topic_t *_topic;
		rd_kafka_topic_conf_t *_topic_conf;
	};
#endif
}